约瑟夫环我想大家都了解,这里再简单介绍下,n, m分别代表
n个人围成圈,编号分别为1~n,从1号开始报数,m号出列,然后重新从1开始报数,到m再出列,直到整个环只剩一个人,输出这个人的编号。最常规的做法当然就是用链表模拟整个操作过程。这种方法,每一个人出列,都要数m次,时间复杂度会达到O(n*m)。
有一种有趣的解法,就是通过反向递推找到元素编号,时间复杂度可以达到O(n)。
做法其实很简单,每次删除一个人后,从下一个报数的人开始重新编号,这个时候,你可以得到原始编号和新编号的映射关系,通过这个关系,就能够方向递推达到最后要删除人的编号。
- 但是要如何找到这个递推式子?我们来看看实际的例子。
假设:n = 8, m = 3。设y为原始编号, x为新编号
原始序列:
x = 1 2 3 4 5 6 7 8
y = 1 2 3 4 5 6 7 8
个数:8
新序列:
x = 6 7 Del 1 2 3 4 5
y = 1 2 4 5 6 7 8
个数:7
接下去,你只要找到x和y之间的映射关系就行了。
怎么找?画个坐标轴看看,其实就是一个分段函数,我这里就不画了,有时间补上。
其实映射关系是:y = (x + m) % i
有这个映射关系,接下去只需要知道x = 1时的值,并知道m的值,然后i从1推到n,最后得到的y值,就是最后要找的值。
约瑟夫环时间复杂度O(n)解法
最新推荐文章于 2021-05-14 15:27:52 发布